package yu

import (
	"os"
	"os/signal"
	"runtime/debug"
)

// IApp 应用实现接口
type IApp interface {
	Name() string
	Servers() []IServer
	OnStart() bool
	OnStop()
}

// IServer 服务实现接口
type IServer interface {
	OnStart() bool
	OnStop()
	Info() string
}

// Run 运行服务
func Run(app IApp) {
	defer func() {
		if err := recover(); err != nil {
			debug.PrintStack()
		}
	}()
	Logf("app %s start", app.Name())
	if !app.OnStart() {
		Logf("app run stop, start return false")
		return
	}
	for _, server := range app.Servers() {
		// 启动的服务有些会阻塞，因此放goroutine中执行
		go func(svr IServer) {
			if !svr.OnStart() {
				Errf("server start failed: %s", svr.Info())
			}
		}(server)
	}
	sig := make(chan os.Signal)
	defer close(sig)
	signal.Notify(sig, os.Interrupt, os.Kill)
	<-sig
	for _, server := range app.Servers() {
		server.OnStop()
	}
	app.OnStop()
	Logf("app %s stop", app.Name())
}
